home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / boot / scsiDiskBoot / fs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-16  |  8.1 KB  |  322 lines

  1. /* fs.c -
  2.  *
  3.  *    General filesystem support.
  4.  *
  5.  * Copyright (C) 1985 Regents of the University of California
  6.  * All rights reserved.
  7.  */
  8.  
  9. #ifdef notdef
  10. static char rcsid[] = "$Header: /sprite/src/boot/scsiDiskBoot/RCS/fs.c,v 1.9 89/06/16 08:29:57 brent Exp $ SPRITE (Berkeley)";
  11. #endif not lint
  12.  
  13. #include "sprite.h"
  14. #include "fsBoot.h"
  15. #include "machMon.h"
  16.  
  17. /*
  18.  * For non-block aligned reads.
  19.  */
  20. char    readBuffer[FS_BLOCK_SIZE];
  21.  
  22. /*
  23.  * For lookup
  24.  */
  25. static char    component[FS_MAX_NAME_LENGTH];
  26.  
  27. /*
  28.  * Forward declarations.
  29.  */
  30. void FsGetFileDesc();
  31. void FsInitFileHandle();
  32.  
  33. /*
  34.  * ----------------------------------------------------------------------------
  35.  *
  36.  * Fs_Open --
  37.  *
  38.  *    Open a file.  This does a simple lookup (based on the kernel's
  39.  *    FsLocalLookup) and creates a handle for the file.
  40.  *
  41.  * Results:
  42.  *    SUCCESS or a return code from various sub-operations.
  43.  *
  44.  * Side effects:
  45.  *    Calls malloc
  46.  *
  47.  * ----------------------------------------------------------------------------
  48.  */
  49.  
  50. ReturnStatus
  51. Fs_Open(fileName, useFlags, permissions, handlePtrPtr)
  52.     char *fileName;
  53.     int useFlags;
  54.     int permissions;
  55.     FsLocalFileIOHandle     **handlePtrPtr;
  56. {
  57.     register ReturnStatus status;
  58.     FsLocalFileIOHandle *curHandlePtr;
  59.     register char *curCharPtr;
  60.     register char *componentPtr;
  61.     register int index;
  62.  
  63.     curCharPtr = fileName;
  64.     while(*curCharPtr == '/') {
  65.     curCharPtr++;
  66.     }
  67.     curHandlePtr = fsRootHandlePtr;
  68.  
  69.     while (*curCharPtr != '\0') {
  70.     if (curHandlePtr->descPtr->fileType != FS_DIRECTORY) {
  71.         return(FS_NOT_DIRECTORY);
  72.     }
  73.         /*
  74.          * Get the next component.
  75.          */
  76.         index = 0;
  77.     componentPtr = component;
  78.         while (*curCharPtr != '/' && *curCharPtr != '\0') {
  79.             *componentPtr++ = *curCharPtr++;
  80.         }
  81.         *componentPtr = '\0';
  82. #ifndef NO_PRINTF
  83.     Mach_MonPrintf(" %s ", component);
  84. #endif
  85.         /*
  86.          * Skip intermediate and trailing slashes so that *curCharPtr
  87.          * is Null when 'component' has the last component of the name.
  88.          */
  89.         while (*curCharPtr == '/') {
  90.             curCharPtr++;
  91.         }
  92.  
  93.     status = FsFindComponent(fsDomainPtr, curHandlePtr, component,
  94.                           &curHandlePtr);
  95.  
  96.     if (status != SUCCESS) {
  97. #ifndef NO_PRINTF
  98.         Mach_MonPrintf("<%x>\n", status);
  99. #endif
  100.         return(status);
  101.     }
  102.     }
  103.     *handlePtrPtr = curHandlePtr;
  104. }
  105.  
  106. /*
  107.  * ----------------------------------------------------------------------------
  108.  *
  109.  * Fs_Read --
  110.  *
  111.  *    Read from a file given its handle.
  112.  *
  113.  * Results:
  114.  *    A return status from the read.
  115.  *
  116.  * Side effects:
  117.  *    buffer is loaded with the data read in.
  118.  *    *readCountPtr is updated to reflect the number of bytes read.
  119.  *
  120.  * ----------------------------------------------------------------------------
  121.  */
  122. ReturnStatus
  123. Fs_Read(handlePtr, offset, numBytes, buffer, readCountPtr)
  124.     register FsLocalFileIOHandle     *handlePtr;
  125.     int            offset;
  126.     int            numBytes;
  127.     register Address    buffer;
  128.     int            *readCountPtr;
  129. {
  130.     int                firstBlock;
  131.     int                lastBlock;
  132.     int                lastByte;
  133.     BlockIndexInfo        indexInfo;
  134.     register    int        readSize;
  135.     register    int        blockAddr;
  136.     register    int        blockOffset;
  137.     register    int        bufferIndex;
  138.     register     ReturnStatus    status;
  139.     register    int        size;
  140.  
  141.     firstBlock = offset / FS_BLOCK_SIZE; 
  142.     lastByte = offset + numBytes - 1;
  143.     if (lastByte > handlePtr->descPtr->lastByte) {
  144.     lastByte = handlePtr->descPtr->lastByte;
  145.     }
  146.     lastBlock = lastByte / FS_BLOCK_SIZE;
  147.  
  148.     (void)FsGetFirstIndex(handlePtr, firstBlock, &indexInfo);
  149.  
  150.     bufferIndex = 0;
  151.     blockOffset = offset & FS_BLOCK_OFFSET_MASK;
  152. #ifdef SCSI0_BOOT 
  153.     Mach_MonPrintf(" read %d at %d into %x\n", numBytes, offset, buffer);
  154. #endif 
  155.  
  156.     while (indexInfo.blockNum <= lastBlock) {
  157.     if (indexInfo.blockNum < lastBlock) {
  158.         size = FS_BLOCK_SIZE - blockOffset;
  159.         readSize = FS_BLOCK_SIZE;
  160.     } else {
  161.         size = (lastByte & FS_BLOCK_OFFSET_MASK) + 1 - blockOffset;
  162.         readSize = size;
  163.     }
  164.     blockAddr = *indexInfo.blockAddrPtr + 
  165.             fsDomainPtr->headerPtr->dataOffset * FS_FRAGMENTS_PER_BLOCK;
  166.     if (blockOffset != 0 || size != FS_BLOCK_SIZE) { 
  167.         status = FsDeviceBlockIO(FS_READ, &fsDevice, blockAddr,
  168.                (readSize - 1) / FS_FRAGMENT_SIZE + 1, readBuffer);
  169.         if (status != SUCCESS) {
  170.         goto readError;
  171.         }
  172.         bcopy(&(readBuffer[blockOffset]), &(buffer[bufferIndex]), size);
  173.     } else {
  174.         status = FsDeviceBlockIO(FS_READ, &fsDevice, blockAddr,
  175.             FS_FRAGMENTS_PER_BLOCK, &(buffer[bufferIndex]));
  176.         if (status != SUCCESS) {
  177.         goto readError;
  178.         }
  179.     }
  180.     bufferIndex += size;
  181.     blockOffset = 0;
  182.     FsGetNextIndex(handlePtr, &indexInfo);
  183.     }
  184.  
  185. readError:
  186.  
  187.     *readCountPtr = bufferIndex;
  188.  
  189.     return(status);
  190. }
  191.  
  192. /*
  193.  *----------------------------------------------------------------------
  194.  *
  195.  * FsFindComponent --
  196.  *
  197.  *
  198.  * Results:
  199.  *    None.
  200.  *
  201.  * Side effects:
  202.  *
  203.  *----------------------------------------------------------------------
  204.  */
  205. ReturnStatus
  206. FsFindComponent(domainPtr, curHandlePtr, component, newHandlePtrPtr)
  207.     FsDomain *domainPtr;
  208.     FsLocalFileIOHandle *curHandlePtr;
  209.     char *component;
  210.     FsLocalFileIOHandle **newHandlePtrPtr;
  211. {
  212.     register ReturnStatus status;
  213.     register int dirOffset;        /* Offset within the directory */
  214.     register int blockOffset;        /* Offset within a directory block */
  215.     register FsDirEntry *dirEntryPtr;    /* Reference to directory entry */
  216.     int length;                /* Length variable for read call */
  217.     register FsLocalFileIOHandle *handlePtr;
  218.  
  219.     dirOffset = 0;
  220.     do {
  221.     length = FS_DIR_BLOCK_SIZE;
  222.     status = Fs_Read(curHandlePtr, dirOffset, length, readBuffer, &length);
  223.     if (status != SUCCESS) {
  224.         return(status);
  225.     }
  226.     if (length == 0) {
  227.         return(FS_FILE_NOT_FOUND);
  228.     }
  229.     dirEntryPtr = (FsDirEntry *)readBuffer;
  230.     blockOffset = 0;
  231.     while (blockOffset < FS_DIR_BLOCK_SIZE) {
  232.         dirEntryPtr = (FsDirEntry *)((int)readBuffer + blockOffset);
  233.         if (dirEntryPtr->fileNumber != 0) {
  234.         /*
  235.          * A valid directory record.
  236.          */
  237.         Mach_MonPrintf("Found %s\n", dirEntryPtr->fileName);
  238.         if (strcmp(component, dirEntryPtr->fileName) == 0) {
  239.             handlePtr = (FsLocalFileIOHandle *)malloc(sizeof(FsLocalFileIOHandle));
  240.             FsInitFileHandle(domainPtr, dirEntryPtr->fileNumber,
  241.                     handlePtr);
  242.             *newHandlePtrPtr = handlePtr;
  243.             return(SUCCESS);
  244.         }
  245.         }
  246.         blockOffset += dirEntryPtr->recordLength;
  247.     }
  248.     dirOffset += FS_DIR_BLOCK_SIZE;
  249.     } while(TRUE);
  250. }
  251.  
  252. /*
  253.  *----------------------------------------------------------------------
  254.  *
  255.  * FsInitFileHandle --
  256.  *
  257.  *    Initialize a file handle.
  258.  *
  259.  * Results:
  260.  *    None.
  261.  *
  262.  * Side effects:
  263.  *    Fills in the file handle that our caller has already allocated.
  264.  *
  265.  *----------------------------------------------------------------------
  266.  */
  267. void
  268. FsInitFileHandle(domainPtr, fileNumber, handlePtr)
  269.     FsDomain *domainPtr;
  270.     int fileNumber;
  271.     register FsLocalFileIOHandle *handlePtr;
  272. {
  273.     register FsFileDescriptor *descPtr;
  274.  
  275.     bzero((Address)handlePtr, sizeof(FsLocalFileIOHandle));
  276.     handlePtr->hdr.fileID.minor = fileNumber;
  277.     descPtr = (FsFileDescriptor *)malloc(sizeof(FsFileDescriptor));
  278.     FsGetFileDesc(domainPtr, fileNumber, descPtr);
  279.     handlePtr->descPtr = descPtr;
  280. }
  281.  
  282. /*
  283.  *----------------------------------------------------------------------
  284.  *
  285.  * FsGetFileDesc --
  286.  *
  287.  *    Read in a file descriptor from the disk.
  288.  *
  289.  * Results:
  290.  *    None.
  291.  *
  292.  * Side effects:
  293.  *    Fills in the file descriptor that our caller has already allocated.
  294.  *
  295.  *----------------------------------------------------------------------
  296.  */
  297. void
  298. FsGetFileDesc(domainPtr, fileNumber, descPtr)
  299.     FsDomain *domainPtr;
  300.     register int fileNumber;
  301.     register FsFileDescriptor *descPtr;
  302. {
  303.     register FsDomainHeader *headerPtr;
  304.     register int         blockNum;
  305.     register int         offset;
  306.  
  307.     headerPtr = domainPtr->headerPtr;
  308.     blockNum = headerPtr->fileDescOffset + fileNumber / FS_FILE_DESC_PER_BLOCK;
  309.     offset = (fileNumber & (FS_FILE_DESC_PER_BLOCK - 1)) *
  310.         FS_MAX_FILE_DESC_SIZE;
  311.  
  312.     (void)FsDeviceBlockIO(FS_READ, &fsDevice, 
  313.                blockNum * FS_FRAGMENTS_PER_BLOCK,
  314.                FS_FRAGMENTS_PER_BLOCK, readBuffer);
  315.     bcopy( readBuffer + offset, descPtr, sizeof(FsFileDescriptor));
  316. #ifndef NO_PRINTF
  317.     if (descPtr->magic != FS_FD_MAGIC) {
  318.     Mach_MonPrintf("desc %d bad <%x>\n", fileNumber, descPtr->magic);
  319.     }
  320. #endif
  321. }
  322.